package com.xbjtech.ticketsystem.controller;

import com.xbjtech.ticketsystem.utils.CaptchaUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.constraints.NotBlank;
import java.util.Iterator;
import java.util.Set;

/**
 * @author: leejun.happy@gmail.com
 * @created: 2019年2月26日
 */
@Controller
@Validated
@Slf4j
public class LoginController {

    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @PostMapping("/login")
    public String login(
            @NotBlank(message = "账号不能为空")
                    String username,
            @NotBlank(message = "密码不能为空")
                    String password,
            @NotBlank(message = "验证码不能为空")
                    String code,
            Boolean rememberMe, Model model) {
        log.info("username:{}, password:{}, remenberMe:{}", username, password, rememberMe);
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        String inputCode = (String) session.getAttribute(CaptchaUtil.SESSION_CODE_NAME);
        if (null == inputCode || !inputCode.equalsIgnoreCase(code)) {
            model.addAttribute("error", "验证码不正确");
            return "login";
        }
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        token.setRememberMe(rememberMe == null ? false : rememberMe);
        try {
            subject.login(token);
            return "redirect:/main";
        } catch (Exception ex) {
            ex.printStackTrace();
            model.addAttribute("error", ex.getMessage());
        }
        return "login";
    }

    @ExceptionHandler({ConstraintViolationException.class})
    public ModelAndView ex(ConstraintViolationException ex) {
        ModelAndView mv = new ModelAndView("login");
        Set<ConstraintViolation<?>> violations = ex.getConstraintViolations();
        Iterator<ConstraintViolation<?>> it = violations.iterator();
        if (it.hasNext()) {
            ConstraintViolation<?> violation = it.next();
            PathImpl propertyPath = (PathImpl) violation.getPropertyPath();
            System.out.println(violation.getInvalidValue());
            mv.addObject(propertyPath.getLeafNode().getName(), violation.getInvalidValue());
            mv.addObject("error", violation.getMessage().toString());
        }
        return mv;
    }

}
